require "button.rb"
#require "launch.rb"

module GUI

#The Widget class is an interface between the button class and the window class which allows for user interaction with an area of the screen. This area is referred to as the widget.
#To make a Widget, simply create a class derived from Widget and override methods as needed:
#
# class MyWidget < Widget      #all widgets are subclasses of Widget
#   attr_reader :text,:font    #most widgets will have text and font attributes
#   def initialize(window,text)
#     super(window,Button::Image,0,400,640,480,"img/gui/mywidget image.png",name="My Widget")       #use super to initialize the button
#     @text=text; @font=Gosu::Font.new(window, "arial", 50)          #initialize widget specific variables
#   end
#   def draw                        #the window will call draw every time it executes GameWindow::draw
#     font.draw(text,0,0)           #you do not have to draw the image here, Button class does that for you
#     if clicked?                   #here you do widget specific things like drawing text,
#       setImage(Gosu::Image.new)   #changing the picture on mouse over or click, etc
#     end                                     
#   end
#   def onDelete        #onDelete is called when the window wants to delete the widget
#     puts "deleted"    #execute widget specific code here
#   end                 #or leave the function alone if there is no widget specific code
# end
#
#See the `Widget Programmer's Handbook` for more info.

class Widget < Button
  attr_reader :window, :name, :sleeping, :defimage, :buttonId, :id, :zfocus
  def initialize(type=Button::Image,x1=0,y1=0,x2=1,y2=1,src="null.png",name="unnamed",acceptsticky=true,z=0) #do not modify
    super(type,x1,y1,x2,y2,src)
    @id=$window.newGuiWidget(self)
    @name=name
    @sleeping=false
    @defimage=src
    @zfocus=z
    @acceptstickyfocus=acceptsticky
    $flog.debug("New Widget") {"ID: "+@id.to_s+", Name: "+@name+", Type: "+self.class.to_s}
    onInitialize
   # if name=="unnamed"
      #puts caller
    #end
  end
  def hasFocus? #do not modify
    if $window.hasFocus == self
      return true 
    else
      return false
    end
  end
  def hasStickyFocus? #do not modify
    if $window.hasStickyFocus == self
      return true 
    else
      return false
    end
  end
  def focus #do not modify
    #debugger
    $window.setFocus(@id) 
    onMouseOver #focus is triggered by the onMouseOver event, so when the window gives a widget focus, it must preform the mouseover event 
  end  
  def blur #do not modify
    onMouseOut #blur is triggered by the onMouseOut event, so when the window blurs a widget, it must preform the mouseout event
  end
    
  def event(type) #do not modify
   #   $flog.debug("Widget Event") {"Type: "+type.to_s+", Owner: "+@id.to_s}
    if type==WidgetEvent::MsLeft
      if @acceptstickyfocus
        stickFocus
      end
      onClick
    elsif type==WidgetEvent::MsRight
      onRightClick
    else
      onKeyPress(type)
    end
  end
  
  def feedText(char)
  end
  def onClick
  end
  def onRightClick
  end
  def onDrag(x1, y1, x2, y2)
  end
  def onRightDrag(x1, y1, x2, y2)
  end
  def onMouseOver
  end
  def onStickyFocus
  end
  def onMouseOut 
  end
  def onStickyBlur
  end
  def onInitialize
  end
  def onDelete
  end
  def onKeyPress(key)
  end
  
  def stickFocus
    $window.setStickyFocus(self)
  end
  def unstickFocus
    $window.setStickyFocus(nil)
  end
  
  def intDraw
    if not @sleeping
      draw
    end
  end
  
  def draw
  end
  
  def sleep
    if not @sleeping
      delImage
      if hasStickyFocus?
        $window.setStickyFocus(nil)
      end
      @sleeping=true
    end
  end
  def sleeping?
    return @sleeping
  end
  def wakeUp
    if @sleeping
      setDefaultImage
      @sleeping=false
    end
  end
  
  def setDefaultImage
    setImage(@defimage)
  end
  
  def button
    return Button.getButton(buttonId)
  end
  
  def del
    onDelete
    if $window.nil?
      $flog.fatal("Window assigned to nil") #very strange bug
      return
    end
    $window.deleteGuiWidget(self)
    super
  end
end

class WidgetEvent
  MsLeft=0
  MsRight=1
  KeyUp=2
  KeyDown=3
  KeyLeft=4
  KeyRight=5
  KeyEscape=6
  KeyEnter=7      
  KeyAlt=8
  KeyControl=9
  KeyShift=10      
  KeySpace=11
  GpEnter=12
  GpCancel=13
  KeyText=14
  KeyDelete=15
  MsLeftDrag=16
  MsRightDrag=17
end

WidgetTextCaps = {
 ","=>"<",
 "."=>">",
 "/"=>"?",
 "'"=>"\"",
 ";"=>":",
 "["=>"{",
 "]"=>"}",
 "\\"=>"|",
 "="=>"+",
 "-"=>"_",
 "0"=>")",
 "9"=>"(",
 "8"=>"*",
 "7"=>"&",
 "6"=>"^",
 "5"=>"%",
 "4"=>"$",
 "3"=>"#",
 "2"=>"@",
 "1"=>"!",
 "`"=>"~"
}

class TextBar < Widget
  attr_reader :text, :actionQue, :advancebutton, :closebutton, :yesnoselect, :script, :yesnoreply
  
  class Action
    def do; end
    def stacks?; return true; end
  end
  class AskAction < Action
    attr_reader :query, :yes, :no
    def initialize(query, yes, no)
      @query=query; @yes=yes; @no=no
    end
    def do
      if @query.strip!=""
        $textbar.setText(@query)
      end
      $textbar.advancebutton.sleep
      $textbar.yesnoselect.wakeUp
    end
    def stacks?; return false; end
  end
  class ReplyAction < Action
    def do
      $textbar.script.respondToAsk($textbar.yesnoreply)
    end
  end
  class TextAction < Action
    attr_reader :text
    def initialize(text)
      @text=text
    end    
    def do
      if @text.strip!=""
        $textbar.setText(@text)
      end
    end
    def stacks?; return false; end
  end
  class SetImageAction < Action
    attr_reader :img
    def initialize(img)
      @img=img
    end    
  end
  class SScriptAction < Action
    attr_reader :code
    def initialize(code)
      @code=code
    end        
    def do
      RubyScript::Utils::SpeechScript::ExecCmd(@code)
    end
  end
  class ClearAction < Action
    def do
      $textbar.clearText
    end
  end
  
  def initialize(name="unnamed",text="")
    if $textbar.class.to_s=="TextBar" #do not create textbar if one is already present
      return
    end
    super(Button::Image,0,400,640,480,"img/gui/textbar/bar.png",name)
    @font = Gosu::Font.new($window, Gosu::default_font_name, 20)
    @textPieces = []
    @text = justify(text)
    @actionQue = []
    @advancebutton = TextBarAdvance.new("Textbar Advance Button")
    @advancebutton.sleep
    @closebutton = TextBarClose.new("Textbar Close Button")
    @closebutton.sleep
    @yesnoselect = YesNoSelect.new("Yes-No Select")
    @yesnoselect.sleep
    @yesnoreply=nil
    #@ask=false
    $textbar=self #preinitialize global variable
    @script = SpeechScript.new("null.rb")
    @cvisible = nil
    $textbar=self
  end
  def justify(text)
    words=text.split
    string=""
    finstring=string
    words.each { |word|
      string+=" "
      string+=word
      finstring+=" "
      finstring+=word
      if @font.text_width(string) >= 615
        finstring+="\n"
        string=""
      end
    }
    @textPieces=finstring.strip.split("\n")
    @textPieces.each {|piece| piece.strip!}
    return text
  end
  def setText(text) #immediately set text, skipping que and filters
    @text=justify(text)
  end
  
  def queAction(action)
    raise "'#{action}' is not a valid TextBar Action" unless action.kind_of?(Object::TextBar::Action)
    if not @closebutton.sleeping? #text is already on the screen, write the new text and activate the advance button
      @actionQue.push(action)
      @closebutton.sleep
      @advancebutton.wakeUp
    elsif @actionQue.empty?
      action.do
      @advancebutton.wakeUp unless action.stacks?
    else 
      @actionQue.push(text)      
    end
  end
  def clearText
    @text=justify("")
  end
  def advance
    if not @actionQue.empty?
      @actionQue[0].do
      @actionQue.shift
      while @actionQue[0].stacks?
        @actionQue[0].do
        @actionQue.shift
      end
    end
    if @actionQue.empty?
      @advancebutton.sleep
      @closebutton.wakeUp
    end
  end
  def sleep
    @closebutton.sleep
    @advancebutton.sleep
    @yesnoselect.sleep
    super
  end
  def hide
    $window.cursor.visible=false unless @cvisible
    @onfinishscript.call(@onfinishscriptargs) if @onfinishscript
    RubyScript::Utils.SetGlobalParameter("SpeechScript", @script.file.path)
    RubyScript::Utils.RunEvent("Finish SpeechScript")
    sleep
  end
  def wakeUp
    @cvisible = $window.cursor.visible?
    $window.cursor.visible=true
    super
  end
  def choose(value)
    @yesnoselect.sleep
    if not @as
      @advancebutton.wakeUp
    end
    if not @cs
      @closebutton.wakeUp
    end
    @yesnoreply=value
    #rest of function = auto advance if possible
    if not @as
      advance
    end
    if not @cs
      hide
    end
  end
  def getChoice
    @as=@advancebutton.sleeping?
    @cs=@closebutton.sleeping?
    @advancebutton.sleep
    @closebutton.sleep
    @yesnoselect.wakeUp
  end
  def loadText(file, proc=nil, args=nil)
    @script=SpeechScript.new(file)
    @onfinishscript=proc
    args=Array.new if args==nil
    @onfinishscriptargs=args
    @script.run
  end
  def onKeyPress(key)
    advance
  end
  def onMouseOver
  end
  def onClick
    stickFocus
  end
  def draw
    i=0
    @textPieces.each {|piece|
      @font.draw(piece, 10, 410+i*@font.height, ZOrder::Text, 1.0, 1.0, 0xff000000)
      i+=1
    }
  end
end

class TextBarAdvance < Widget
  def initialize(name="unnamed")
    super(Button::Image,603,451,633,473,"img/gui/textbar/arrow.png",name,false,1)
  end
 # def setImage(src)
  #  super(src)
   # puts "here"
   # puts caller
 # end
  def onClick
    $textbar.advance
  end
  def onMouseOver
    setImage("img/gui/textbar/arrowup.png") 
  end
  def onMouseOut
    setImage("img/gui/textbar/arrow.png")
  end
end

class TextBarClose < Widget
  def initialize(name="unnamed")
    super(Button::Image,603,451,633,473,"img/gui/textbar/x.png",name,false,1)
  end
  def onClick
    $textbar.hide
  end
  def onMouseOver
    setImage("img/gui/textbar/xup.png")
  end
  def onMouseOut
    setImage("img/gui/textbar/x.png")
  end
end

class YesNoSelect < Widget
  attr_reader :font, :yes, :no
  YesProc = Proc.new {
    $textbar.choose(true)
  }
  NoProc = Proc.new {
    $textbar.choose(false)
  }
  def initialize(name="unnamed")
    super(Button::Image,560,330,640,400,"img/gui/yesnoselect/bg.png",name)
    @font=Gosu::Font.new($window, Gosu::default_font_name, 25)
    @font.draw_rel("Yes", 600, 360, ZOrder::Text, 0.5, 0.5, 1.0, 1.0, 0xff000000)
    @font.draw_rel("No", 600, 380, ZOrder::Text, 0.5, 0.5, 1.0, 1.0, 0xff000000) 
    #@selected=false
    #@selection=true
    @yes=GenericButton.new("Yes Button",self,"null.png","img/gui/yesnoselect/bevup.png","img/gui/yesnoselect/bevup.png",565,334,635,365,YesProc,false,1)
    @no=GenericButton.new("No Button",self,"null.png","img/gui/yesnoselect/bevup.png","img/gui/yesnoselect/bevup.png",565,365,635,396,NoProc,false,1)
  end
  def sleep
    @yes.sleep
    @no.sleep
    super
    #puts @sleeping
    #puts button.image.src
  end
  def wakeUp
    @yes.wakeUp
    @no.wakeUp
    super
  end
  def draw
    @font.draw_rel("Yes", 600, 350, ZOrder::Text, 0.5, 0.5, 1.0, 1.0, 0xff000000)
    @font.draw_rel("No", 600, 380, ZOrder::Text, 0.5, 0.5, 1.0, 1.0, 0xff000000)     
  end
end

class GenericButton < Widget
  attr_reader :overImage, :onClickPrc
  def initialize(name="unnamed", parent=nil, img="null.png", overImg="null.png", dimg = "null.png", x1=1, y1=1, x2=2, y2=2, onClickPrc=Proc.new, asticky=true, z=0)
    super(Button::Image,x1,y1,x2,y2,img,name.to_s+" < Generic Button",asticky,z)
    @overImage=overImg
    @parent=parent
    @onClickPrc=onClickPrc
    @enabled = true
    @dimg = dimg
  end
  def onClick
    @onClickPrc.call(@parent) if @enabled
  end
  def onMouseOver
    setImage(@overImage) if @enabled
  end
  def onMouseOut
    setDefaultImage if @enabled
  end
  def disable
    @enabled = false
    setImage(@dimg)
  end
  def enable
    @enabled = true
    setDefaultImage
  end
  def enabled?
    return @enabled
  end
end

class PauseMenu < Widget
  def initialize(name)
    super(Button::Image, 1, 1, 2, 2, "null.png", name)
  end
end

class DebugConsole < Widget
  @@allow=false
  def initialize(name="unnamed")
    super(Button::Image, 0, 0, 640, 480, "null.png", name)
    @font=Gosu::Font.new($window, Gosu::default_font_name, 20)
    @vline=0
    @oldtext=[]
    @textm=false
    clear
  end  
  def onKeyPress(key)
    if key==WidgetEvent::KeyDelete
      thisline=@text[@line]
      if @text and thisline.length>0
        @text[@line]=thisline.slice(0,thisline.length-1)
      elsif thisline.length>3
        @text[@line]=thisline.slice(0,thisline.length-1)
      end
    elsif key==WidgetEvent::KeySpace
      @text[@line]+=" "
    elsif key==WidgetEvent::KeyEscape
      sleep
    elsif key==WidgetEvent::KeyEnter
      if @textm
        if @text[@line]=="/endtext"
          @textm=false
          @line+=1
          @text[@line]=">> "
        else
          @line+=1
          @text[@line]=""
        end
        return
      end
      @oldtext.push @text[@line]
      cmd=@text[@line].slice(3,@text[@line].length-3)
      if cmd.slice(cmd.size-3,3)=="/nl"
        @text[@line]=@text[@line].slice(0,@text[@line].length-3)
        @text[@line+1]="|> "
        @line+=1
      else
        runcmd(cmd)
      end
      @vline=@oldtext.size
    elsif key==WidgetEvent::KeyUp
      if @vline-1 >= 0 and 
        @vline-=1
        @text[@line]=@oldtext[@vline]
      end
    elsif key==WidgetEvent::KeyDown
      if @vline+1 < @oldtext.size and 
        @vline+=1
        @text[@line]=@oldtext[@vline]
      end
    end
  end
  def feedText(char)
    @text[@line]+=char.to_s unless char=="`"
    #puts ":"+char.to_s+":"
    #gets
  end
  def justify(ln)
    fin=""
    size=ln.size
    while ln.size>70
      fin+=ln.slice(0,70)+"\fNL"
      ln=ln.slice(70,ln.size)
    end
    fin+=ln.to_s
    return fin
  end
  def respond(text)
    text=text.to_s
    @line+=1
    if text==""
      text="<no output>"
    end
    text=justify(text) if text.index("\fNL")==nil
    text=text.split("\fNL")
    mult=false
    text.each { |ln|
      if ln.slice(0,4)=="\fERR"
        @text[@line]="!> "+ln.strip
      else
        @text[@line]="^> "+ln
      end
      @line+=1
      @text[@line]=">> "
    }
  end
  def clear
    @text=[]
    @text[0]="CONSOLE"
    @text[1]="#########"
    @text[2]="<Press ` (backquote) or enter '/exit' to exit>"
    @text[3]=">> "
    @line=3    
    @vline=@oldtext.size-1
  end
  private
  def runcmd(cmd)
    if cmd.slice(0,1)=="/"
      if cmd=="/exit"
        sleep
      elsif cmd=="/clear"
        clear
      elsif cmd=="/menu"
        sleep
        StartMenu.new.start
      elsif cmd=="/help"
        respond("Enter a Ruby command to execute it\fNLEnter '/' followed by a word to execute a console command\fNLFor a list of console commands, enter '/list'")
      elsif cmd=="/list"
        respond("/clear\fNL/clearhist\fNL/cursor\fNL/endtext\fNL/exit\fNL/help\fNL/hist\fNL/list\fNL/menu\fNL/text")
      elsif cmd=="/hist"
        resp=""
        @oldtext.each { |item|
          resp+="\fNL"
          resp+=item
        }
        respond(resp)
      elsif cmd=="/text"
        @textm=true
        @line+=1
        @text[@line]=""
      elsif cmd=="/clearhist"
        @oldtext=[]
        @vline=0
      elsif cmd=="/cursor"
        ax = $window.mouse_x; ay = $window.mouse_y
        mx = $window.camera.x + ax; my = $window.camera.y + ay
        nx = $window.map.nodeMap.nodeAt(mx, my)[0]; ny = $window.map.nodeMap.nodeAt(mx, my)[1]
        respond("Cursor Visible: #{$window.cursor.visible?}\fNLAbs Coords: (#{ax}, #{ay})\fNLMap Coords: (#{mx}, #{my}) (Traversable: #{$window.map.traversable?(mx.to_i, my.to_i)})\fNLMap Node: (#{nx} ,#{ny}) (Traversable: #{$window.map.nodeMap.traversable?(nx, ny)})")
      end
      return
    end
    output=eval("begin\n"+cmd+"\nrescue\n'\fERR: '+$@[0]+': '+$!\nend",TOPLEVEL_BINDING)
    #print output.to_s+":\n"
    respond(output)
  end
  public
  def sleep
    @text=[]
    @line=0
    @vline=0
    super
  end
  def wakeUp
    @oldtext=[]
    @vline=0
    @text=false
    clear
    stickFocus
    super
  end
  def onStickyFocus
    $window.setTextInput(@textinput)
  end
  def onStickyBlur
    $window.setTextInput(nil)
  end
  def DebugConsole.enabled=(bool)
    @@allow=bool
  end
  def DebugConsole.enabled
    return @@allow
  end
  def draw
    i=0
    @text.each {|line|
      @font.draw(line, 10, 10+i*@font.height, ZOrder::Text, 1.0, 1.0, 0xffffffff)
      i+=1
    }
  end
end

class TracePanel < Widget
  @@allow=false
  def initialize(name)
    super(Button::Image,0,0,640,60,"img/gui/trace/bg.png",name)
    @font=Gosu::Font.new($window, Gosu::default_font_name, 20)
    clear
  end
  def onKeyPress(key)
    if key==WidgetEvent::KeyDelete
      sleep
    elsif key==WidgetEvent::KeyEnter
      clear
    end
  end
  def sput(text)
    @line+=1
    @text[@line]=text.to_s    
  end
  def put(text)
    @line+=1
    @text[@line]=text.to_s
    wakeUp
  end
  def <<(text)
    sput(text)
  end
  def *(nullarg=nil)
    wakeUp
  end
  def ~()
    sleep
  end
  def pause
    gets
  end
  def clear
    @text=[]
    @text[0]="TRACE OUTPUT"
    @text[1]="Press DELETE to close, ENTER to clear. (Click to activate.)"
    @line=2
  end
  def TracePanel.enabled=(bool)
    if bool==true
      @@allow=true
    else
      @@allow=false
    end
  end
  def TracePanel.enabled
    return @@allow
  end
  def draw
    i=0
    @text.each {|line|
      @font.draw(line, 10, 10+i*@font.height, ZOrder::Text, 1.0, 1.0, 0xffffffff)
      i+=1
    }
  end
end

class HealthMeter < Widget
  attr_accessor :containers, :hearts
  def initialize(name, x, y)
    super(Button::Image, x, y, x, y, "null.png", name, false)
    @containers=0
    @hearts=0
    @x=x
    @y=y
    delImage
    @container_img = Gosu::Image.new($window, "img/gui/healthmeter/container.png")
    @heart_img = Gosu::Image.new($window, "img/gui/healthmeter/heart.png")
    @hheart_img = Gosu::Image.new($window, "img/gui/healthmeter/halfheart.png")
  end
  def draw
    ri=0
    @containers.times { |i|
      ri=i-1
      @container_img.draw(@x+25*ri, @y, ZOrder::Button)
    }
    (@hearts/2).floor.times { |i|
      ri=i-1
      @heart_img.draw(@x+25*ri+2, @y+2, ZOrder::Button)
    }
    cx=@x+25*ri+2
    (@hearts%2).times { |i|
      ri=i-1
      @hheart_img.draw(cx+25*ri+2, @y+2, ZOrder::Button)
    }
  end
end

class TextBox < Widget
  CaretColor=0xff646464
  TextColor=0xff646464
  SelColor=0xff33FFFF
  TextPadding=5
  def initialize(name, x, y, len=12, fontheight=20, fontname=Gosu::default_font_name, img="img/gui/generic/textbox.png", oimg="img/gui/generic/textboxactive.png")
    @font=Gosu::Font.new($window, fontname, fontheight)
    @textinput=Gosu::TextInput.new
    @img,@oimg=img,oimg
    img=Gosu::Image.new($window, @img)
    @offsety=((img.height-@font.height)/2).floor
    super(Button::Image, x, y, x+img.width, y+img.height, @img, name)
    @maxlength=len
    @x=x
    @y=y
    @drawcursor=0
    @realwidth=@x + TextPadding
  end
  def onMouseOver
    setImage(@oimg) unless self.hasStickyFocus?
  end
  def onMouseOut
    setImage(@img) unless self.hasStickyFocus?
  end
  def onMouseClick
    stickFocus
  end
  def onStickyFocus
    setImage(@oimg)
    $window.setTextInput(@textinput)
  end
  def onStickyBlur
    setImage(@img)
    $window.setTextInput(nil)
  end
  def width
    return @maxlength
  end
  def text
    return @textinput.text
  end
  def text=(val)
    val=val.slice(0,12) if val.size>12
    @textinput.text = val
  end
  def draw
    text=@textinput.text.slice(0,12)
    if self.hasStickyFocus?
      pos_x = @x + @font.text_width(@textinput.text[0...@textinput.caret_pos]) + TextPadding
      sel_x = @x + @font.text_width(@textinput.text[0...@textinput.selection_start]) + TextPadding
      @realwidth+=@font.text_width(text)
      if pos_x > @realwidth
        pos_x=@realwidth+1 
        sel_x=@realwidth+1
        @textinput.text=text
      end
      @realwidth-=@font.text_width(text)
      if @drawcursor < 18
        $window.draw_line(pos_x, @y+@offsety, CaretColor, pos_x, @y+@font.height+@offsety, CaretColor, ZOrder::Text)
      elsif @drawcursor > 36
        @drawcursor=0
      end
      @drawcursor+=1
      $window.draw_quad(sel_x, @y+@offsety, SelColor, pos_x, @y+@offsety, SelColor, sel_x, @y+@font.height+@offsety, SelColor, pos_x, @y+@font.height+@offsety, SelColor, ZOrder::Text-0.5)
    end
    @font.draw(text, @x+TextPadding, @y+@offsety, ZOrder::Text, 1, 1, TextColor)
  end
end

class SelectionBox < Widget
  attr_reader :items
  def initialize(name, x,y, retproc)
    super(Button::Image, x, y, x+380, y+380, "img/gui/generic/selbox.png", name)
    @items=[]
    @x,@y=x,y
    @retproc=retproc
    @scroll = VertScroll.new(name + " Scroll Wdgt", self, x+350, y+172)
  end
  def newItem(text, value)
    ypos=@y+5+5+@items.size*25
    visible = (not(ypos>250))
    @items.push(SelectionItem.new(self.id, text, value, @x+5, ypos, visible))
  end
  def choose(val)
    @retproc.call(val)
  end
  def scrollUp
    
  end
  def scrollDown
    
  end
  class SelectionItem < Widget
    TextColor=0xff000000
    OverTextColor=0xff555555
    attr_reader :text, :value, :parent
    def initialize(parent, text, value, x, y, visible)
      super(Button::Image, x, y, x+290, y+25, "null.png", name)
      delImage
      sleep unless visible
      @x,@y=x,y
      @parent=parent
      @text,@value=text,value
      @text=@text.sub(0,9)+"..." if @text.size>12
      @font = Gosu::Font.new($window, Gosu::default_font_name, 24)
    end
    def onMouseOver
      setImage("img/gui/generic/selhighlight.png")
    end
    def onMouseOut
      delImage
    end
    def onClick
      $window.guiWidgets[@parent].choose(@value)
    end
    def move(x,y)
      @x, @y=x, y
    end
    def draw
      if not hasFocus?
        @font.draw(@text, @x+20, @y, ZOrder::Text, 1, 1, TextColor)
      else
        @font.draw(@text, @x+20, @y, ZOrder::Text, 1, 1, OverTextColor)        
      end
    end
  end
end

class ThemeButton < Widget
  TextColor=0xff000000
  def initialize(name, text, x, y, onClickPrc=Proc.new)
    super(Button::Image,x,y,x+100,y+30,"img/gui/generic/button.png",name)
    @font = Gosu::Font.new($window, Gosu::default_font_name, 17)
    @text=text
    @onClickPrc=onClickPrc
    @drawx=x+((100-@font.text_width(@text))/2).floor
    @drawy=y+((30-@font.height)/2).floor
  end
  def x1=
    super
    @drawx=x+((100-@font.text_width(@text))/2).floor
  end
  def y1=
    super
    @drawy=y+((30-@font.height)/2).floor
  end
  def onClick
    @onClickPrc.call
  end
  def onMouseOver
    setImage("img/gui/generic/buttonup.png")    
  end
  def onMouseOut
    setDefaultImage
  end
  def draw
    @font.draw(@text, @drawx, @drawy, ZOrder::Text, 1, 1, TextColor)
  end
end

class Minimap < Widget
  
end

class MagicMeter < Widget
  attr_accessor :value
  def initialize(name, x, y)
    super(Button::Image,x,y,x+20,y+200,"img/gui/magicmeter/meter.png",name,false)
    @x, @y=x, y
    @fillimg=Gosu::Image.new($window, "img/gui/magicmeter/fill.png", true)
    @value=0
  end
  def draw
    @fillimg.draw(@x+6, @y+200-10-@value*2, ZOrder::Button+0.5, 1, @value*2)
  end
end

class MenuBar < Widget
  def initialize(name)
    super(Button::Image,0,0,640,40,"img/gui/generic/menubar.png",name,false)
    @hiding,@showing=false
    @buttons=[]
    @bwidth=10
    @bheight=5
    sleep
  end
  def onMouseOut
    hide
  end
  def onMouseOver
    wakeUp
    show
  end
  def sleep
    @buttons.each { |button| button.sleep }
    super
  end
  def wakeUp
    super
    @buttons.each { |button| button.wakeUp } 
  end
  def show
    @hiding=false
    @showing=true
  end
  def hide
    @showing=false
    @hiding=true
  end
  def addButton(button)
    width=button.x2-button.x1
    height=button.y2-button.y1
    @bwidth+=5
    button.x1=@bwidth
    button.y1=@bheight
    button.x2=@bwidth+width
    button.y2=@bheight+height
    @buttons.push(button)
    @bwidth+=width
  end
  def draw
    if @showing
      image.y+=1
      @buttons.each { |button| button.y1+=1; button.y2+=1; }
      if image.y>=0
        image.y=0
        @showing=false
      end
    elsif @hiding
      image.y-=1
      @buttons.each { |button| button.y1-=1; button.y2-=1; }
      if image.y<=-30
        image.y=-30
        @hiding=false
        sleep
      end
    end
  end
end

=begin
class VertScrollBar < Widget
  def initialize(name, x, y, height)
    super(Button::Image,x,y,x+20,y+200,"null.png",name,false)
    @x, @y = x, y
    @len = height
    @fillimg=Gosu::Image.new($window, "img/gui/generic/scrollbg.png", true)
  end
  def draw
    @fillimg.draw(@x, @y, ZOrder::Button+0.5, 1, @len)
  end
end

class HorizScrollBar < Widget
  def initialize(name, x, y, width)
    super(Button::Image,x,y,x+20,y+200,"null.png",name,false)
    @x, @y = x, y
    @len = width
  end
end
=end

class VertScroll < Widget
  attr_reader :parent
  def initialize(name, parent, x, y)
    super(Button::Image,0,0,0,0,"null.png",name,false)  
    @parent = parent
    @up = ScrollUp.new(name+" Up Btn", self, x, y)
    @down = ScrollDown.new(name+" Down Btn", self, x, y+19)
  end
  def sleep
    @up.sleep
    @down.sleep
    super
  end
  def wakeUp
    @up.wakeUp
    @down.wakeUp
    super
  end
  class ScrollUp < GenericButton
    UpProc = Proc.new { |parent| parent.parent.scrollUp }
    def initialize(name, parent, x, y)
      super(name, parent, "img/gui/scroll/arrowup.png", "img/gui/scroll/oarrowup.png", "img/gui/scroll/arrowup.png", x, y, 23+x, 16+y, UpProc) 
    end
  end
  class ScrollDown < GenericButton
    DownProc = Proc.new { |parent| parent.parent.scrollDown }
    def initialize(name, parent, x, y)
      super(name, parent, "img/gui/scroll/arrowdown.png", "img/gui/scroll/oarrowdown.png", "img/gui/scroll/arrowdown.png", x, y, 23+x, 16+y, DownProc)
    end
  end
end

end #module GUI

include GUI